#pragma once

#include <CGalaxyParams.h>
#include <CMatrix.h>
#include <CComponentParams.h>
#include <quaternion.h>

class CGalaxyComponent {
 public:

  CGalaxyParams* params;
  CComponentParams componentParams;

  CMatrix RX;

  Perlin* perlin;
  double strength;

  double average, count;

  double bulgeDust;
  double rotSign;
  quaternion quat;
  CMatrix rotmat, rotmatFull;

  CVector quatRot;

  double setupQuaternions();

  double* rA;
  double* rB;


  CGalaxyComponent(CGalaxyParams* p, CComponentParams cp) {
    params = p;
    perlin = params->perlin;
    componentParams = cp;
    count = 0;
    average = 0;
    //    quat = quaternion(0, params->orientation*-1);
    setupQuaternions();
  }

  virtual double calculateIntensity(double intensity, CVector& p, double iscale) = 0;
   
  double getRadialIntensity(double rad) {
    return CMath::Minmax(exp(-rad/componentParams.r0) - 0.05,0,1);
  }


  double getHeightModulation(double height) {
    double val = 1.0/cosh(height/componentParams.z0);
    return val*val;
  }

  //  double calculateComponent(CVector isp1, CVector isp2);
  double getRadius(const CVector& p, CVector& P, double& h);
  double getHeightWeight(double height);
  double getPerlinCloudNoise(const CVector& p, double rad, double t, int N, double ks, double kadd); 

  double findDifference(double t1, double t2);
  double getArm(double rad, CVector p, double disp);
  
  double getTheta(const CVector& p);
  double getWinding(const double& rad);
  
  double calculateArmValue(double rad, CVector& P, double armStrength);

};
